// 设置请求统一信息
import axios from "axios"
import qs from "qs"
import store from "@/store/index.js"
import { $message } from "./msg-box.js"

const isProd = process.env.NODE_ENV === "production"

axios.defaults.baseURL = isProd ? `${window.location.origin}/${store.state.system.api}` : store.state.system.api
const service = axios.create({
  timeout: 300000, // 超时设置
  withCredentials: true, // 跨域请求
})

let hasLogoutStatus = false // 是否某个请求存在需要退出的状态

const queue = [] // 请求队列

const { CancelToken } = axios // axios内置的中断方法

/**
 * 拼接请求的url和方法；
 * 同样的`url + method` 可以视为相同的请求
 * @param {Object} config 请求头对象
 */
const token = (config) => `${config.url}_${config.method}`

/**
 * 中断重复的请求，并从队列中移除
 * @param {Object} config 请求头对象
 */
const removeQueue = (config) => {
  for (let i = 0, size = queue.length; i < size; i += 1) {
    const task = queue[i]
    if (!task) return
    // 出现401，403状态码中断后续请求
    const isLogout = token(config).includes("logout")
    // 退出接口跳过中断逻辑
    if (!isLogout && hasLogoutStatus) {
      task.token()
      queue.splice(i, 1)
    } else {
      const cancelMethods = ["post", "put", "delete"] // 需要中断的请求方式
      const { method } = config
      if (cancelMethods.includes(method)) {
        if (task.token === token(config)) {
          task.cancel()
          queue.splice(i, 1)
        }
      }
    }
  }
}

/**
 * 请求错误统一处理
 * @param {Object} response 错误对象
 */
const errorHandle = (response) => {
  const { status, data: { message = "" } } = response
  let msg = message
  if (!message) {
    switch (status) {
      case 401:
        msg = "您没有权限访问此操作！"
        break
      case 403:
        msg = "您的登录状态已失效，请重新登录。"
        break
      case 424:
        msg = response.data.error
        break
      default:
        msg = "服务请求异常，请刷新重试。"
    }
  }
  hasLogoutStatus = status === 401 || status === 403
  if (hasLogoutStatus) {
    $message.error(msg, () => {
      store.dispatch("Logout")
    })
  }
  $message.error(msg)
}

/**
 * 修改开发环境下mock配置
 * @param {Object} config 请求配置
 */
const mockApi = (config) => {
  if (!isProd) {
    const isMock = config.url.includes("/mock")
    if (isMock) {
      const api = config.url.match(/\/api(.+)/g)
      // config.url = `http://${window.location.host}${api}`;
      config.url = `${api}`
      return config
    }
  }
}

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 中断之前的同名请求
    // removeQueue(config)
    // 添加cancelToken
    config.cancelToken = new CancelToken((c) => {
      queue.push({ token: token(config), cancel: c })
    })
    // 登录后添加token
    if (store.getters.token) {
      config.headers.Authorization = `${store.getters.token.token_type} ${store.getters.token.access_token}`
    }
    // mockApi(config)
    return config
  },
  (error) => Promise.reject(error),
)

// 响应拦截器
service.interceptors.response.use(
  (response) =>
     response.data
    // 在请求完成后，自动移出队列
    // removeQueue(response.config)
    // // // 关闭全局按钮Loading响应
    // // store.commit("cancalLoading")
    // // 错误码处理

    // if (response.status !== 200) {
    //   return Promise.reject(response)
    // }
    // console.log("status", response.data.data)
    // return Promise.resolve(response.data)
  ,
  (error) => {
    const { response } = error
    if (response) {
      // 错误处理
      errorHandle(response)
      return Promise.reject(response)
    }
    // 请求超时
    if (error.message?.includes("timeout")) {
      // console.log("超时了");
      $message.error("请求已超时，请刷新或检查互联网连接")
    } else {
      // 断网，可以展示断网组件
      // console.log("断网了");
      $message.error("请检查网络是否已连接")
    }
  },
)

export default service

// export default {
//   get: (url, data = {}) => new Promise((resolve, reject) => {
//     service
//       .get(url, { params: data })
//       .then((response) => {
//         resolve(response.data)
//       })
//       .catch((error) => {
//         reject(error)
//       })
//   }).catch((error) => {
//     throw new Error(error)
//   }),
//   // post: service.post,
//   post: (url, data = {}) => new Promise((resolve, reject) => {
//     service
//       .post(url, data, {
//         // headers: {
//         //   "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
//         // },
//         headers: { "Content-Type": "application/json" },
//         withCredentials: true,
//         // transformRequest: [
//         //   (reqData) => qs.stringify(reqData),
//         // ],
//       })
//       .then((response) => {
//         console.log("response:",url, response)
//         resolve(response?.data)
//       })
//       .catch((error) => {
//         console.log("response:",url, error)
//         reject(error)
//       })
//   }).catch((error) => Promise.reject(error)),
//   put: (url, data = {}) => new Promise((resolve, reject) => {
//     service
//       .put(url, data, {
//         headers: {
//           "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
//         },
//         withCredentials: true,
//         transformRequest: [
//           (reqData) => qs.stringify(reqData),
//         ],
//       })
//       .then((response) => {
//         resolve(response.data)
//       })
//       .catch((error) => {
//         reject(error)
//       })
//   }).catch((error) => Promise.reject(error)),
//   putJson: (url, data = {}) => new Promise((resolve, reject) => {
//     service
//       .put(url, data, {
//         headers: { "Content-Type": "application/json" },
//         withCredentials: true,
//       })
//       .then((response) => {
//         resolve(response.data)
//       })
//       .catch((error) => {
//         reject(error)
//       })
//   }).catch((error) => Promise.reject(error)),
//   postJson: (url, data = {}) => new Promise((resolve, reject) => {
//     service
//       .post(url, data, {
//         headers: { "Content-Type": "application/json" },
//         withCredentials: true,
//       })
//       .then((response) => {
//         resolve(response.data)
//       })
//       .catch((error) => {
//         reject(error)
//       })
//   }).catch((error) => Promise.reject(error)),
//   delete: (url, data = {}) => new Promise((resolve, reject) => {
//     service
//       .delete(url, {
//         data,
//       })
//       .then((response) => {
//         resolve(response.data)
//       })
//       .catch((error) => {
//         reject(error)
//       })
//   }).catch((error) => Promise.reject(error)),
//   deleteJson: (url, data = {}) => new Promise((resolve, reject) => {
//     service
//       .delete(url, {
//         headers: { "Content-Type": "application/json" },
//         withCredentials: true,
//         data,
//       })
//       .then((response) => {
//         resolve(response.data)
//       })
//       .catch((error) => {
//         reject(error)
//       })
//   }).catch((error) => Promise.reject(error)),
//   /**
//    * blob下载
//    * @param {String} url 请求地址
//    * @param {String} method 请求方式 默认`get`
//    * @param {Object} data 请求数据
//    */
//   exportFile({ url = "", data = {}, method = "get" }) {
//     return new Promise((resolve, reject) => {
//       const isPost = method.toLocaleUpperCase() === "POST"
//       const postConfig = isPost
//         ? { headers: { "Content-Type": "application/json" }, data }
//         : { params: data }
//       const downConfig = {
//         withCredentials: true,
//         method: method.toLocaleLowerCase(),
//         responseType: "blob",
//         ...postConfig,
//       }
//       // eslint-disable-next-line no-unexpected-multiline
//       service(url, downConfig)
//         .then((response) => {
//           resolve(response)
//         })
//         .catch((error) => {
//           reject(error)
//         })
//     }).catch((error) => Promise.reject(error))
//   },
// }
